#include "logmanager.h"
#include "ui_logmanager.h"
#include "logworker.h"
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QMessageBox>
#include <QDebug>
#include <QDateTime>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>

// 静态成员初始化
LogWorker* LogManager::s_logWorker = nullptr;
QMutex LogManager::s_workerMutex;

LogManager::LogManager(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::LogManager),
    logModel(nullptr),
    refreshTimer(new QTimer(this))
{
    ui->setupUi(this);

    // 初始化异步日志工作线程
    initLogWorker();

    setupUI();
    setupModel();
    setupConnections();

    // 设置自动刷新定时器
    connect(refreshTimer, &QTimer::timeout, this, &LogManager::refreshLogs);

    // 连接日志工作线程的信号
    if (s_logWorker) {
        connect(s_logWorker, &LogWorker::logWritten,
                this, &LogManager::onLogWritten, Qt::QueuedConnection);
        connect(s_logWorker, &LogWorker::autoExportCompleted,
                this, &LogManager::onAutoExportCompleted, Qt::QueuedConnection);
        connect(s_logWorker, &LogWorker::errorOccurred,
                this, &LogManager::onLogWorkerError, Qt::QueuedConnection);
    }
}

LogManager::~LogManager()
{
    if (refreshTimer->isActive()) {
        refreshTimer->stop();
    }
    delete ui;
}

void LogManager::initLogWorker()
{
    QMutexLocker locker(&s_workerMutex);

    if (!s_logWorker) {
        s_logWorker = new LogWorker();
        s_logWorker->setAutoExportThreshold(500); // 默认500条
        s_logWorker->start();
        qDebug() << "日志工作线程已初始化并启动";
    }
}

void LogManager::cleanupLogWorker()
{
    QMutexLocker locker(&s_workerMutex);
    if (s_logWorker) {
        s_logWorker->stop();
        s_logWorker->wait(5000);
        delete s_logWorker;
        s_logWorker = nullptr;
    }

    // ✅ 清理命名连接
    if (QSqlDatabase::contains("LogUIConnection")) {
        QSqlDatabase::removeDatabase("LogUIConnection");
    }
}

void LogManager::setupUI()
{
    // 设置时间范围控件
    ui->startDateTimeEdit->setDateTime(QDateTime::currentDateTime().addDays(-7));
    ui->endDateTimeEdit->setDateTime(QDateTime::currentDateTime());

    // 设置日志类型筛选
    ui->logTypeComboBox->addItem("所有类型", "");
    ui->logTypeComboBox->addItem("系统日志", "SYSTEM");
    ui->logTypeComboBox->addItem("操作日志", "OPERATION");
    ui->logTypeComboBox->addItem("告警日志", "ALARM");
    ui->logTypeComboBox->addItem("错误日志", "ERROR");

    // 设置自动刷新间隔
    ui->refreshIntervalSpinBox->setRange(5, 300);
    ui->refreshIntervalSpinBox->setValue(30);

    // 设置表格属性
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tableView->setAlternatingRowColors(true);
    ui->tableView->setSortingEnabled(true);

    qDebug() << "日志管理界面初始化完成,已启用异步日志和自动导出功能(100条)";
}

void LogManager::setupModel()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "LogUIConnection");
        db.setDatabaseName("D:/sqlite/system.db");
        if (!db.open()) {
            qDebug() << "日志UI数据库连接失败:" << db.lastError().text();
            return;
        }

        logModel = new QSqlTableModel(this, db); // 使用命名连接
        logModel->setTable("system_logs");
        logModel->setEditStrategy(QSqlTableModel::OnManualSubmit);

    logModel->setHeaderData(0, Qt::Horizontal, "日志ID");
    logModel->setHeaderData(1, Qt::Horizontal, "时间戳");
    logModel->setHeaderData(2, Qt::Horizontal, "日志类型");
    logModel->setHeaderData(3, Qt::Horizontal, "日志级别");
    logModel->setHeaderData(4, Qt::Horizontal, "内容");
    logModel->setHeaderData(5, Qt::Horizontal, "用户ID");
    logModel->setHeaderData(6, Qt::Horizontal, "设备ID");

    logModel->setSort(1, Qt::DescendingOrder);

    if (logModel->select()) {
        ui->tableView->setModel(logModel);

        ui->tableView->setColumnWidth(0, 60);
        ui->tableView->setColumnWidth(1, 150);
        ui->tableView->setColumnWidth(2, 100);
        ui->tableView->setColumnWidth(3, 80);
        ui->tableView->setColumnWidth(4, 400);
        ui->tableView->setColumnWidth(5, 60);
        ui->tableView->setColumnWidth(6, 80);

        ui->statusLabel->setText(QString("共 %1 条日志记录").arg(logModel->rowCount()));
    } else {
        qDebug() << "日志表查询失败:" << logModel->lastError().text();
        ui->statusLabel->setText("日志表查询失败");
    }
}

void LogManager::setupConnections()
{
    connect(ui->queryButton, &QPushButton::clicked, this, &LogManager::onQueryButtonClicked);
    connect(ui->resetButton, &QPushButton::clicked, this, &LogManager::onResetButtonClicked);
    connect(ui->clearButton, &QPushButton::clicked, this, &LogManager::onClearLogsClicked);
    connect(ui->autoRefreshCheckBox, &QCheckBox::toggled, this, &LogManager::onAutoRefreshToggled);
    connect(ui->logTypeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &LogManager::onLogTypeChanged);
    connect(ui->btnExport, &QPushButton::clicked, this, &LogManager::onExportLogsClicked);
}

void LogManager::refreshLogs()
{
    if (!logModel) return;
    logModel->select();
    ui->statusLabel->setText(QString("共 %1 条日志记录").arg(logModel->rowCount()));
}
void LogManager::onQueryButtonClicked()
{
    applyFilters();
}

void LogManager::onResetButtonClicked()
{
    ui->startDateTimeEdit->setDateTime(QDateTime::currentDateTime().addDays(-7));
    ui->endDateTimeEdit->setDateTime(QDateTime::currentDateTime());
    ui->logTypeComboBox->setCurrentIndex(0);
    ui->keywordLineEdit->clear();

    if (logModel) {
        logModel->setFilter("");
        logModel->select();
        ui->statusLabel->setText(QString("共 %1 条日志记录").arg(logModel->rowCount()));
    }
}

void LogManager::onClearLogsClicked()
{
    int ret = QMessageBox::warning(this, "确认",
                                 "确定要清空所有日志记录吗?此操作不可恢复!",
                                 QMessageBox::Yes | QMessageBox::No);

    if (ret == QMessageBox::Yes) {
        QSqlQuery query;
        if (query.exec("DELETE FROM system_logs")) {
            QMessageBox::information(this, "成功", "日志记录已清空");
            refreshLogs();
        } else {
            QMessageBox::critical(this, "错误", "清空日志失败: " + query.lastError().text());
        }
    }
}

void LogManager::onAutoRefreshToggled(bool checked)
{
    if (checked) {
        int interval = ui->refreshIntervalSpinBox->value() * 1000;
        refreshTimer->start(interval);
    } else {
        refreshTimer->stop();
    }
}

void LogManager::onLogTypeChanged(int index)
{
    Q_UNUSED(index)
    applyFilters();
}

void LogManager::onExportLogsClicked()
{
    logOperation(-1, "导出日志", "用户开始导出日志到TXT文件", "", "");

    if (!logModel || logModel->rowCount() == 0) {
        QMessageBox::information(this, "提示", "当前没有日志数据可导出");
        logOperation(-1, "导出日志", "导出失败:没有日志数据", "", "");
        return;
    }

    QString fileName = QFileDialog::getSaveFileName(
        this,
        "导出日志文件",
        QString("系统日志_%1.txt").arg(QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss")),
        "文本文件 (*.txt)"
    );

    if (fileName.isEmpty()) {
        logOperation(-1, "导出日志", "用户取消导出操作", "", "");
        return;
    }

    if (!fileName.endsWith(".txt", Qt::CaseInsensitive)) {
        fileName += ".txt";
    }

    if (exportLogsToTxt(fileName)) {
        QMessageBox::information(this, "导出成功",
                                QString("日志已成功导出到:\n%1\n\n共导出 %2 条记录")
                                .arg(fileName).arg(logModel->rowCount()));

        logOperation(-1, "导出日志",
                   QString("导出成功,文件: %1,记录数: %2")
                   .arg(fileName).arg(logModel->rowCount()), "", "");
    } else {
        QMessageBox::critical(this, "导出失败", "日志导出失败,请检查文件路径和权限");
        logOperation(-1, "导出日志",
                   QString("导出失败,文件: %1").arg(fileName), "", "");
    }
}

void LogManager::applyFilters()
{
    if (!logModel) return;

    QStringList filters;

    QDateTime startTime = ui->startDateTimeEdit->dateTime();
    QDateTime endTime = ui->endDateTimeEdit->dateTime();
    filters.append(QString("timestamp >= '%1'").arg(startTime.toString("yyyy-MM-dd HH:mm:ss")));
    filters.append(QString("timestamp <= '%2'").arg(endTime.toString("yyyy-MM-dd HH:mm:ss")));

    QString logType = ui->logTypeComboBox->currentData().toString();
    if (!logType.isEmpty()) {
        filters.append(QString("log_type = '%1'").arg(logType));
    }

    QString keyword = ui->keywordLineEdit->text().trimmed();
    if (!keyword.isEmpty()) {
        filters.append(QString("content LIKE '%%1%'").arg(keyword));
    }

    QString filter = filters.join(" AND ");
    logModel->setFilter(filter);

    if (logModel->select()) {
        ui->statusLabel->setText(QString("共 %1 条日志记录").arg(logModel->rowCount()));
    } else {
        qDebug() << "日志过滤失败:" << logModel->lastError().text();
    }
}

void LogManager::applyUserPermissions()
{
    if (currentUserRole == "user") {
        ui->queryButton->setEnabled(false);
        ui->resetButton->setEnabled(false);
        ui->clearButton->setEnabled(false);
        ui->autoRefreshCheckBox->setEnabled(false);
        ui->refreshIntervalSpinBox->setEnabled(false);
        ui->logTypeComboBox->setEnabled(false);
        ui->keywordLineEdit->setEnabled(false);
        ui->startDateTimeEdit->setEnabled(false);
        ui->endDateTimeEdit->setEnabled(false);

        ui->statusLabel->setText("普通用户无权限访问日志管理");

        if (logModel) {
            logModel->setFilter("1=0");
            logModel->select();
        }
    }
}

bool LogManager::exportLogsToTxt(const QString& filePath)
{
    QFile file(filePath);

    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        logError(QString("无法打开文件进行写入: %1, 错误: %2")
                   .arg(filePath).arg(file.errorString()));
        return false;
    }

    QTextStream out(&file);
    out.setCodec("UTF-8");

    out << "========================================\n";
    out << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss") << "\n";
    out << "========================================\n\n";

    out << QString("%1\t%2\t%3\t%4\t%5\t%6\t%7\n")
           .arg("日志ID", -8)
           .arg("时间戳", -19)
           .arg("日志类型", -10)
           .arg("日志级别", -8)
           .arg("内容", -50)
           .arg("用户ID", -8)
           .arg("设备ID", -8);

    out << QString().fill('-', 120) << "\n";

    for (int row = 0; row < logModel->rowCount(); ++row) {
        QString logId = logModel->data(logModel->index(row, 0)).toString();
        QString timestamp = logModel->data(logModel->index(row, 1)).toString();
        QString logType = logModel->data(logModel->index(row, 2)).toString();
        QString logLevel = logModel->data(logModel->index(row, 3)).toString();
        QString content = logModel->data(logModel->index(row, 4)).toString();
        QString userId = logModel->data(logModel->index(row, 5)).toString();
        QString deviceId = logModel->data(logModel->index(row, 6)).toString();

        content = content.replace("\n", " ").replace("\t", " ");

        if (content.length() > 100) {
            content = content.left(100) + "...";
        }

        out << QString("%1\t%2\t%3\t%4\t%5\t%6\t%7\n")
               .arg(logId, -8)
               .arg(timestamp, -19)
               .arg(logType, -10)
               .arg(logLevel, -8)
               .arg(content, -50)
               .arg(userId, -8)
               .arg(deviceId, -8);
    }

    out << "\n========================================\n";
    out << QString("总计导出 %1 条日志记录\n").arg(logModel->rowCount());
    out << "========================================\n";

    file.close();

    logSystem("日志管理模块",
             QString("日志导出成功,文件: %1,记录数: %2")
             .arg(filePath).arg(logModel->rowCount()));

    return true;
}

void LogManager::setAutoExportThreshold(int threshold)
{
    QMutexLocker locker(&s_workerMutex);
    if (s_logWorker) {
        s_logWorker->setAutoExportThreshold(threshold);
        qDebug() << "自动导出阈值已设置为:" << threshold;
    }
}

int LogManager::getCurrentLogCount()
{
    QMutexLocker locker(&s_workerMutex);
    if (s_logWorker) {
        return s_logWorker->getCurrentLogCount();
    }
    return 0;
}

// ==================== 异步日志槽函数 ====================

void LogManager::onLogWritten(int totalCount)
{
    // 每100条更新一次UI,避免频繁刷新
    static int lastDisplayCount = 0;

    if (totalCount - lastDisplayCount >= 100 || totalCount % 100 == 0) {
        refreshLogs();
        lastDisplayCount = totalCount;
    }
}

void LogManager::onAutoExportCompleted(const QString& filePath, int exportedCount)
{
    // 自动导出完成,刷新界面
    refreshLogs();

    // 显示通知
    QString message = QString("日志自动导出完成!\n"
                            "已导出 %1 条日志记录\n"
                            "文件位置: %2\n"
                            "数据库已清空,重新开始记录")
                     .arg(exportedCount)
                     .arg(filePath);

    QMessageBox::information(this, "自动导出完成", message);

    // 发出信号通知其他组件
    emit autoExportCompleted(filePath, exportedCount);

    qDebug() << "日志自动导出完成:" << filePath << ",导出记录数:" << exportedCount;
}

void LogManager::onLogWorkerError(const QString& error)
{
    qDebug() << "日志工作线程错误:" << error;
    ui->statusLabel->setText("日志系统错误: " + error);
}

// ==================== 静态日志记录方法(异步) ====================

void LogManager::logOperation(int userId, const QString& action, const QString& details,
                             const QString& ipAddress, const QString& userAgent)
{
    if (!s_logWorker) {
        initLogWorker();
    }

    if (!s_logWorker) {
        qDebug() << "日志工作线程未初始化,无法记录日志";
        return;
    }

    QString logContent = QString("[操作] %1").arg(action);
    if (!details.isEmpty()) {
        logContent += QString(" | 详情: %1").arg(details);
    }
    if (!ipAddress.isEmpty()) {
        logContent += QString(" | IP: %1").arg(ipAddress);
    }
    if (!userAgent.isEmpty()) {
        logContent += QString(" | 客户端: %1").arg(userAgent);
    }

    LogEntry entry(QDateTime::currentDateTime(), "OPERATION", "INFO",
                   logContent, userId > 0 ? userId : 0, 0);

    s_logWorker->addLog(entry);
}

void LogManager::logSystem(const QString& module, const QString& details)
{
    if (!s_logWorker) {
        initLogWorker();
    }

    if (!s_logWorker) {
        qDebug() << "日志工作线程未初始化,无法记录日志";
        return;
    }

    QString logContent = QString("[系统-%1] %2").arg(module).arg(details);

    LogEntry entry(QDateTime::currentDateTime(), "SYSTEM", "INFO",
                   logContent, 0, 0);

    s_logWorker->addLog(entry);
}

void LogManager::logAlarm(int alarmId, const QString& alarmContent, int userId, int deviceId)
{
    if (!s_logWorker) {
        initLogWorker();
    }

    if (!s_logWorker) {
        qDebug() << "日志工作线程未初始化,无法记录日志";
        return;
    }

    QString logContent = QString("[告警] ID:%1 | %2").arg(alarmId).arg(alarmContent);

    LogEntry entry(QDateTime::currentDateTime(), "ALARM", "WARNING",
                   logContent, userId > 0 ? userId : 0, deviceId > 0 ? deviceId : 0);

    s_logWorker->addLog(entry);
}

void LogManager::logError(const QString& errorDetails, int userId)
{
    if (!s_logWorker) {
        initLogWorker();
    }

    if (!s_logWorker) {
        qDebug() << "日志工作线程未初始化,无法记录日志";
        return;
    }

    QString logContent = QString("[错误] %1").arg(errorDetails);

    LogEntry entry(QDateTime::currentDateTime(), "ERROR", "ERROR",
                   logContent, userId > 0 ? userId : 0, 0);

    s_logWorker->addLog(entry);
}

void LogManager::setCurrentUserRole(const QString &role)
{
    this->currentUserRole = role;
    applyUserPermissions();
}
